package com.jacob.androidstudy.androidnote.activity;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.view.Window;

/**
 * Activity是Android程序组件之一。Activity提供供用户交互的界面，例如拨号、拍照、发送邮件、查看地图等。
 * 每个Activity都和一个窗口绑定，此窗口即用来显示用户界面。窗口通常占满屏幕，但是也可以小于屏幕并显示在其他窗口上面。
 * 
 * Android程序一般包含多个Activity。通常，其中一个Activity被指定为“Main Activity”，第一次启动程序时展现给用户。
 * 每个Activity可以启动其他Activity，以实现不同的功能。每启动一个新的Activity，前一个Activity就停止。
 * 系统用栈的方式保存Activity，启动新的Activity时，Activity被放入栈中，并得到用户焦点。Activity栈遵循“后进先出”的队列原则，所以当用户使用完当前Activity，按下“返回”键，当前Activity会被从栈中弹出并销毁，前一个Activity恢复运行。
 * 
 * 当一个Activity因为启动其他Activity而停止时，这个状态变化通过Activity生命周期的回调方法通知我们。
 * 由于Activity状态的改变（包括系统创建、停止、恢复或销毁Activity），可能执行的回调方法有多个。
 * 每次状态改变时的回调都提供执行自定义代码的机会。例如，Activity停止时，应该释放网络连接或数据库连接之类的大对象，Activity恢复时，再次获取必要的资源，恢复中断的Activity。这些状态变动都是Activity生命周期的一部分。
 * 
 * 
 * 
 * 
 * 
 * 
 * Activity的实现步骤：
 * 1 定义Activity，并继承于android.app.Activity。
 * 2 在AndroidManifest.xml中注册Activity。
 *  2.1 Activity必须在AndroidManifest.xml中注册，才能在系统中生效。
 *  2.2 注册Activity时，“android:name”属性是唯一一个必选属性。一旦发布了程序，这个属性就不应该改变了，否则会破坏某些程序功能（例如桌面快捷方式）。
 *  2.3 若不希望Activity被其他程序启动，不给其定义intent-filter即可。反之，则需要定义intent-filter标签，action标签（必选）、category标签（可选）和data标签（可选）。
 * 3 定义layout目录中的显示界面xml文件。
 *   3.1 最常见的设计界面的方式，是使用程序资源目录下的XML文件。这样，可以将用户界面和业务代码分开维护。
 *   3.2 Activity的用户界面由android.view.View类及其子类提供。每个View对象在Activity的窗口中控制一块四边形，并可以响应用户的操作。例如，View对象可以是一个按钮，当用户点击时，触发某些动作。
 *   3.3 Android提供了很多内置的View，可以用来设计组织界面。也可以自定义View类和ViewGroup类的子类，实现自定义的组件。
 * 4 在onCreate()方法中调用this.setContentView()，传入XML文件的资源ID，将其设置为Activity的显示界面。（Activity在构造的时候，会绑定一个Window对象。setContentView()方法实际上是将View和Window绑定。）。
 * 5 还可以在Activity代码中，动态的对显示界面进行改变。
 * 
 * Activity的状态：
 * 1.Resumed
 * Activity生成时，依次调用onCreate()方法、onStart()方法、onResume()方法。
 * 此时Activity处于Resumed状态，也叫运行状态。
 * 此时，Activity在屏幕显示并拥有用户的焦点。
 * 
 * 2.Paused
 * 当Resumed状态的Activity被其他Activity拿走焦点后，调用onPause()方法。
 * 此时Activity处于Paused状态。
 * 当Activity重新得到焦点后，调用onResume()方法，Activity又会回到Resumed状态。
 * 当系统需要释放内存给其他程序时，处于Paused状态的Activity可能会被直接杀死，此时Activity消亡。
 * 
 * 3.Stopped
 * 当Paused状态的Activity被遮挡，不可见后，调用onStop()方法。
 * 此时Activity处于Stopped状态。
 * 当Activity重新得到焦点后，调用onRestart()方法、onStart()方法、onResume()方法，Activity又会回到Resumed状态。
 * 当系统需要释放内存给其他程序时，处于Stopped状态的Activity可能会被直接杀死，此时Activity消亡。
 * 
 * 4.Destroyed
 * 当程序退出后，调用onDestroy()方法。
 * 此时Activity消亡。
 * 
 * 
 * 
 * Activity状态的保存与恢复
 * 1.Activity在进入Paused状态或者Stopped状态之前，会先调用onSaveInstanceState(Bundle outState)方法，将需要保存的数据放入Bundle对象。
 * 2.若Activity被系统杀死之前，重新回到Resumed状态。因为Activity是完好无损的，所以不需要回复其数据。
 * 3.若Activity被系统杀死后，重新又被生成，此时系统会调用onCreate()方法，并传入Bundle对象，用户就可以用Bundle对象恢复Activity的数据和状态。若没有数据需要恢复，系统会传入null。
 * 4.虽然onRestoreInstanceState(Bundle savedInstanceState)方法也会在Activity重新生成时被调用，但是根据官网的说法，最好用onCreate(Bundle savedInstanceState)方法。
 * 
 * 
 * Activity中大型对象的保存与恢复（不要求掌握）
 * 1.需要保存和恢复大型对象时，用onSaveInstanceState()方法就不太合适。此时需要用onRetainNonConfigurationInstance()方法。
 * 2.将需要保存的对象，在onRetainNonConfigurationInstance()方法中返回。
 * 3.然后在onCreate()方法中，使用getLastNonConfigurationInstance()方法，即可返回保存的对象。
 * 4.不要试图保存、恢复与Activity关联的对象，例如Drawable对象、Adapter对象、View对象，或者其他和Context相关的对象。 
 * 
 * 
 * 
 * Activity配置改变时，自己处理
 * 1.在系统配置改变时（例如横竖屏旋转、语言变更等），系统会默认的销毁并重建Activity。但在某些时候，我们希望手工处理这些改变。
 * 2.在AndroidManifest.xml中设置Activity的android:configChanges属性，覆盖onConfigurationChanged(Configuration newConfig)方法。
 * 3.例如，在AndroidManifest.xml中设置某Activity的android:configChanges="orientation|locale"，就表示在横竖屏旋转或语言变更时，系统不会销毁并重启该Activity，而是调用他的onConfigurationChanged(Configuration newConfig)方法。
 * 4.对于大多数的程序，官方不推荐自己处理配置改变。
 * 
 * 
 * 
 * Activity任务和Activity栈
 * 1.Activity任务是指，由多个Activity组成，按照一定顺序的完整的一个业务逻辑。
 * 2.例如，在ActivityA中启动ActivityB，然后在ActivityB中启动ActivityC。这3个Activity就属于同一个Task，拥有相同的TaskID。
 * 3.一个任务中的Activity是采用栈的方式启动和返回的。上例中，在ActivityC中按“Back键”，就会回到ActivityB。
 * 4.一个任务中的Activity可能是，也可能不是同一个程序的，但是他们都属于同一个任务，拥有相同的TaskID。
 * 5.
 * 
 * 
 */
public class Android四大组件之Activity extends Activity{
	
	/**
	 * 必须实现本方法。系统创建Activity时，调用这个方法。
	 * 实现方法时，应该初始化必要的组件，并且必须调用setContentView()，将layout（XML文件）中添加的各种View组件绑定到Activity。
	 * 
	 * 
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
//		将layout/main.xml和本Activity绑定
		this.setContentView(android.R.layout.activity_list_item);
		
//		得到和本Activity绑定的Window对象
		Window w = this.getWindow();
		
//		根据ID得到View对象。只能得到当前绑定界面中存在的View对象。
		this.findViewById(android.R.id.button1);
		
		
		
	}
	
	/**
	 * Activity失去用户焦点时，系统调用本方法。
	 * 因为Activity可能得到，也可能再也得不到用户焦点，实现方法时，一般应该对所作的更改做提交。
	 * 
	 */
	@Override
	protected void onPause() {
		super.onPause();
	}
	
	
	
	
	public void 通过绝对类路径名启动组件() {
//		1.生成一个Intent对象。传入当前组件的对象，和要启动的目标组件的class对象。
		Intent i = new Intent(this,Activity.class);
		
//		2.用Intent对象的put()方法，可以传入需要传递的Extra信息。（KEY+VALUE）
		i.putExtra("姓名", "王超");
		
//		3.调用startActivity()。传入Intent对象。
		this.startActivity(i);
		
//		4.如果需要得到目标组件的返回值，调用startActivityForResult()。传入Intent对象和requestCode。
		this.startActivityForResult(i,65535);
		
	}
	
	public void 通过IntentFilter启动组件() {
//		1.生成一个Intent对象。
		Intent i = new Intent();
		
//		2.调用Intent对象的setAction()、setData()、setFlags()方法。启动组件时，就会启动整个系统中（不光是本工程里面），同时符合设置条件的组件。
		i.setAction("android.intent.action");
		i.setData(Uri.parse("uri"));
		i.setFlags(10);
		
//		3.用Intent对象的put()方法，可以传入需要传递的Extra信息。（KEY+VALUE）
		i.putExtra("姓名", "王超");
		
//		4.调用startActivity()。传入Intent对象。
		this.startActivity(i);
		
//		5.如果需要得到目标组件的返回值，调用startActivityForResult()。传入Intent对象和requestCode。
		this.startActivityForResult(i,65535);
		
		
	}
	
	
	public void 从传入的Intent对象中获取和改变消息() {
//		1.调用getIntent()得到传入的Intent对象。
		Intent i = this.getIntent();
		
//		2.调用Intent对象的getgetData()、getDataString()方法，得到data。
		i.getDataString();
		
//		3.调用Intent对象的getExtras()得到Bundle对象。
		Bundle b = i.getExtras();
		
//		4.调用Bundle对象的 getXXX()得到Extra信息。
		String s = b.getString("姓名");
		
//		5.调用Bundle对象的putXXX()改变Extra信息。
		b.putString("姓名", "王超");
		
		
	}
	
	
	public void 设置返回值并结束组件() {
//		1.调用setResult()，传入ResultCode和Intent对象。
		this.setResult(255, this.getIntent());
		
//		2.调用finish()方法，即可结束当前的组件对象。并返回调用者。
		this.finish();
		
	}



	/**
	 * 当调用的组件结束并返回后，此方法会自动被调用。
	 * requestCode，就是调用组件时传入的。
	 * resultCode和data，就是被调用组件setResult()方法设置的。
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == Activity.RESULT_OK) {
			
		} else if (resultCode == Activity.RESULT_CANCELED) {
			
		}
		
	}



	/**
	 * Activity在进入Paused状态或者Stopped状态之前，会先调用本方法，将需要保存的数据放入Bundle对象。
	 * 
	 * android.app.Activity.onSaveInstanceState()方法中，已经将大多数的UI控件（例如文本框、复选框等）的数据保存了。所以覆盖时，不要忘了执行“super.onSaveInstanceState(outState)”。另外，确保组件都有ID。
	 * 
	 * 本方法只适合用来存储Activity的临时数据。若要存储永久数据，应该写在onPause()方法中。
	 * 
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		super.onSaveInstanceState(outState);
		
//		使用Bundle对象的putXXX()方法存储临时数据。
		outState.putString("key", "value");
		
	}


	/**
	 * 
	 */
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		// TODO Auto-generated method stub
		super.onConfigurationChanged(newConfig);
	}








	


	
	
	

}
